﻿/*************************************************************************************
 * 工    具：  HK_RoamingCam
 * 
 * 描    述：  HK_RoamingCam 是一套漫游相机管理系统，适用于虚拟展厅类相机控制，主要功能如下：
 
 *            PC端、WebGL端、Android端虚拟展厅类相机控制管理工具；
 *            支持通过鼠标点击、手指触摸两种方式进行交互；
 *            视角控制分为：第一人称漫游、三维俯视漫游、鸟瞰正交漫游三种模式；
 *            第一人称漫游（RoamView）：通过点击地面标识点进行位移（依赖Unity Navigation）；
 *            鸟瞰正交漫游（BirdView）：上帝视角进行观察，相机为 Orthographic
 *            三维俯视漫游（ThreeDView）：上帝视角进行观察，相机为 Perspective；
 *             
 * 使    用：  1.在本项目的 Architecture 中注册 IHK_RoamingCamSystem;
 *            2.将 HK_RoamingCamController 中的 Architecture 修改为本项目的 Architecture；
 *            3.在场景中设置好Navigation Static，并进行 Navigation烘焙，生成合适的NavMesh；
 *            4.在场景中指定 RoamView 使用的 Point点位（附带HK_Point脚本），并设置好LookAtType；
 *            5.在场景中指定好 BirdView和ThreeDView 使用的 OverlookPos及RotAroundTarget;
 *            6.将HK_RoamPlayer预设体放入场景中，并进行初始化设置；
 *            7.参考Test_UIRoamCamCtrl，进行视角切换设置；
 * 
 * 依    赖：  Dotween
 * 
 * 版    本：  V1.0
 * 作    者：  谭潇杰、京产肠饭
 * 
 * 创    建：  2023/05/03  V1.0
 * 
 * 链    接：  https://gitee.com/JingChanChangFan/hk_-unity-tools
*************************************************************************************/

using QFramework;
using System.Collections.Generic;

namespace HKTools
{
    public enum ViewMode
    {
        RoamView, // 第一人称漫游
        BirdView,  // 鸟瞰俯视
        ThreeDView   // 透视俯视  
    }

    public interface IHK_RoamingCamSystem : ISystem
    {
        // 是否是移动端
        bool IsMobile { get; set; }

        BindableProperty<bool> IsCanRotCam { get; }
        BindableProperty<ViewMode> CurViewMode { get; }

        // 场景中所有的 RoamPoint
        List<HK_Point> points { get; set; }

        // 上一个位移过来的点位
        HK_Point LastPoint { get; set; }

        /// <summary>
        /// 初始化 RoamingCamSystem 系统层，是否为移动端使用
        /// </summary>
        void InitRoamingCamSystem(bool isMobile);

        /// <summary>
        /// 改变 摄像机 模式
        /// </summary>
        void ChangeViewMode(ViewMode viewMode, HK_Point point = null);

        /// <summary>
        /// 切换 第一人称漫游 点位
        /// </summary>
        /// <param name="point"></param>
        void SwitchRoamPoint(HK_Point point);
    }

    public class HK_RoamingCamSystem : AbstractSystem, IHK_RoamingCamSystem
    {
        public bool IsMobile { get; set; }

        public BindableProperty<bool> IsCanRotCam { get; } = new BindableProperty<bool>();

        public BindableProperty<ViewMode> CurViewMode { get; } = new BindableProperty<ViewMode>();

        public List<HK_Point> points { get; set; }

        public HK_Point LastPoint { get; set; }

        protected override void OnInit()
        {
            IsCanRotCam.Value = true;
            CurViewMode.Value = ViewMode.RoamView;
            points = new List<HK_Point>();
        }

        public void InitRoamingCamSystem(bool isMobile)
        {
            IsMobile = isMobile;
        }

        public void ChangeViewMode(ViewMode viewMode, HK_Point point = null)
        {
            switch (viewMode)
            {
                case ViewMode.RoamView:
                    if (point == null)
                    {
                        this.SendEvent(new Event_ChangeToRoamView()
                        {
                            _point = LastPoint == null ? points[0] : LastPoint,
                            //_point = LastPoint,
                            _lastViewMode = CurViewMode.Value
                        }); ;
                    }
                    else
                    {
                        this.SendEvent(new Event_ChangeToRoamView()
                        {
                            _point = point,
                            _lastViewMode = CurViewMode.Value
                        });
                        LastPoint = point;
                    }
                    break;
                case ViewMode.BirdView:
                    IsCanRotCam.Value = false;
                    this.SendEvent<Event_ChangeToBirdView>();
                    break;
                case ViewMode.ThreeDView:
                    IsCanRotCam.Value = false;
                    this.SendEvent(new Event_ChangeToThreeDView()
                    {
                        _lastViewMode = CurViewMode.Value
                    });
                    break;
            }

            CurViewMode.Value = viewMode;
        }

        public void SwitchRoamPoint(HK_Point point)
        {
            IsCanRotCam.Value = false;
            this.SendEvent(new Event_SwitchRoamPoint() { _point = point });
            LastPoint = point;
        }
    }
}